﻿    var PageController = function (viewController) {
        // Name of page
        self = this;
        self.viewController = viewController;
        self.spaMode = false;

        //Page Model
        var pageModel;

        self.InitializePage = function () {
            window.PageController = self;

            self.viewController.transmittingStyle = ko.observable("hidden");
            self.viewController.savedStyle = ko.observable("hidden");
            self.viewController.loadedStyle = ko.observable("hidden");
            self.viewController.failedStyle = ko.observable("hidden");
            self.viewController.deletedStyle = ko.observable("hidden");
            self.viewController.lastStatus = ko.observable("loading...");

            self.element = document.getElementById("pageHeader");
            if (self.element != null) {
                ko.applyBindings(self, self.element);
            }
            /*
            if (loadFunctions == null)
            {
                loadFunctions = new Array();
            }
            // When the view loads, it may create a set of javascript functions to load (such as instantiating client-side viewModels for the view, etc.)
            for (i = 0; i < loadFunctions.length; i++) {
                loadFunctions[i]();
            }*/
            window.PageController.viewController.lastStatus("");


            if (!self.spaMode) {
                return;
            } else {
                self.CallForPageView();
            }
        };


    var self = this;
    this.lastStatus = ko.observable();
    this.LoadCSS = function (href) {
        var cssLink = $("<link>");
        $("head").append(cssLink); 

        cssLink.attr({
            rel: "stylesheet",
            type: "text/css",
            href: href + "?" + Math.random()
        });
    };

    this.removeScript = function (filename, filetype) {

        if (filename != null && filename.length > 0 && filename.indexOf("/") != 0)
            filename = "/" + filename;

        var targetelement = (filetype == "js") ? "script" : (filetype == "css") ? "link" : "none" 
        var targetattr = (filetype == "js") ? "src" : (filetype == "css") ? "href" : "none" 
        var allsuspects = document.getElementsByTagName(targetelement)
        for (var i = allsuspects.length; i >= 0; i--) { 
            if (allsuspects[i] && allsuspects[i].getAttribute(targetattr) != null && allsuspects[i].getAttribute(targetattr).indexOf(filename) != -1) {
                allsuspects[i].parentNode.removeChild(allsuspects[i]) 
            }
        }
    }

    this.OpenPage = function (gotoLocation) {

        if (!self.spaMode) {
            var location = gotoLocation;
            if (!(location.substring(0, 1) == "/")) {
                location = "/" + location;
            }

            var uri = config.contextPath + location.substring(1);
            var hash = "";
            if (uri.indexOf("#") > -1) {
                hash = uri.substring(uri.indexOf("#") + 1);
                uri = uri.substring(0, uri.indexOf("#"))
            }

            if (hash != "") {
                window.location.hash = hash;
            }

            window.location.href = uri;
        }
        else {
            if (window.PageController != null && window.PageController.pageInfo != null && window.PageController.pageInfo.CustomScripts != null && window.PageController.pageInfo.CustomScripts() != null && window.PageController.pageInfo.CustomScripts().length > 0) {
                pageController.removeScript(window.PageController.pageInfo.CustomScripts(), "css");
            }

            loadFunctions = new Array();
            var pathItems = location.split('/');
            window.DefaultViewController.pageName = '';
            window.DefaultViewController.itemIdentifier = '';

            window.DefaultViewController.controllerName = pathItems[1];
            if (pathItems.length > 2) {
                window.DefaultViewController.pageName = pathItems[2];
            }
            if (pathItems.length > 3) {
                window.DefaultViewController.itemIdentifier = pathItems[3];
            }


            if (typeof (window.history.pushState) == 'function') {
                window.history.pushState("object or string", "Title", config.contextPath + location.substring(1));
            }

            window.DefaultViewController.ReInitialize();
        }
    };

    this.IsArray = function (variable) {
        if (variable != null && variable.constructor.toString().indexOf("Array") == -1)
            return false;
        else
            return true;
    }

    this.createCookie = function (name, value, days) {
        var expires;

        if (days) {
            var date = new Date();
            date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
            expires = "; expires=" + date.toGMTString();
        } else {
            expires = "";
        }
        document.cookie = escape(name) + "=" + escape(value) + expires + "; path=/";
    }

    this.readCookie = function (name) {
        var nameEQ = escape(name) + "=";
        var ca = document.cookie.split(';');
        for (var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) === ' ') c = c.substring(1, c.length);
            if (c.indexOf(nameEQ) === 0) return unescape(c.substring(nameEQ.length, c.length));
        }
        return null;
    }

    this.eraseCookie = function (name) {
        pageController.createCookie(name, "", -1);
    }
};

/**
 * Avoid `console` errors in browsers that lack a console.
 */

(function () {
    var method;
    var noop = function noop() { };
    var methods = [
		'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
		'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
		'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
		'timeStamp', 'trace', 'warn'
    ];
    var length = methods.length;
    var console = (window.console = window.console || {});

    while (length--) {
        method = methods[length];

        // Only stub undefined methods.
        if (!console[method]) {
            console[method] = noop;
        }
    }
}());

window.onerror = function (msg, url, line) {
    logError(msg, arguments.callee.trace());
}

function logError(ex, stack, resultJson) {
    if (ex == null) return;
    if (logErrorUrl == null) {
        alert('logErrorUrl must be defined.');
        return;
    }


    var url = ex.fileName != null ? ex.fileName : document.location;
    if (stack == null && ex.stack != null) stack = ex.stack;

    // format output
    var out = ex.message != null ? ex.name + ": " + ex.message : ex;
    out += ": at document path '" + url + "'.";
    if (pageController.IsArray(stack)) {
        if (stack != null) out += "\n  at " + stack.join("\n  at ");
    }
    else {
        if (stack != null) out += "\n  at " + stack;
    }

    // todo : report different messages based on role
    if (window.PageController != null) {
        window.PageController.lastStatus("Error Occurred\n" + out);
    }

    // send error message
    jQuery.ajax({
        type: 'POST',
        url: logErrorUrl,
        data: { message: out }
    });
}

Function.prototype.trace = function () {
    return;
    var trace = [];
    var current = this;
    while (current) {
        trace.push(current.signature());
        current = current.caller;
    }
    return trace;
}

Function.prototype.signature = function () {
    var signature = {
        name: this.getName(),
        params: [],
        toString: function () {
            var params = this.params.length > 0 ?
                "'" + this.params.join("', '") + "'" : "";
            return this.name + "(" + params + ")"
        }
    };
    if (this.arguments) {
        for (var x = 0; x < this.arguments.length; x++)
            signature.params.push(this.arguments[x]);
    }
    return signature;
}

Function.prototype.getName = function () {
    if (this.name)
        return this.name;
    var definition = this.toString().split("\n")[0];
    var exp = /^function ([^\s(]+).+/;
    if (exp.test(definition))
        return definition.split("\n")[0].replace(exp, "$1") || "anonymous";
    return "anonymous";
}
